/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   13-7-12 下午1:32 Created by sky
 */
package com.jade.modules.number.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.inject.Named;

import com.jade.modules.number.NumberManager;
import com.jade.modules.number.NumberPattern;

/**
 * 简单的号码管理器。
 *
 * @author sky
 * @version 1.0 13-7-12 下午1:32
 */
@Named ("module_numberManager")
public class SimpleNumberManager
        implements NumberManager
{
    protected static final String CMCC_PATTERN = "(15[0-2]|15[7-9]|13[4-9]|147|182|183|184|187|188|178)[0-9]{8}";
    protected static final String UNICOM_PATTERN = "(155|156|13[0-2]|145|185|186|176)[0-9]{8}";
    protected static final String CTC_PATTERN = "(133|153|180|181|189|177)[0-9]{8}";
    protected static final String VIRTUAL_PATTERN = "(170)[0-9]{8}";

    protected Map<String, String> operatorMap = new HashMap<String, String>();

    protected String mobilePattern = "(13[0-9]|15[0-9]|18[0-9]|14[57]|17[0-9])[0-9]{8}";
    protected String numberPattern = "([0+])[0-9]{3,15}";

    protected String defaultCountry = "86";
    protected NumberPattern defaultPattern = NumberPattern.NO_DEF_COUNTRY_CODE;
    protected static final String INT_PREFIX = "+";
    protected static final String INT_PREFIX2 = "00";
    protected String[] nationalPrefix = {"0"};

    @PostConstruct
    public void init()
    {
        operatorMap.put("cmcc", CMCC_PATTERN);
        operatorMap.put("unicom", UNICOM_PATTERN);
        operatorMap.put("ctc", CTC_PATTERN);
        operatorMap.put("virtual", VIRTUAL_PATTERN);
    }

    public String formatNumber(String number)
    {
        return formatNumber(number, defaultPattern);
    }

    public String formatNumber(String number, NumberPattern pattern)
    {
        if (number.startsWith(defaultCountry)) {
            if (pattern.equals(NumberPattern.STANDARD)) {
                return INT_PREFIX + number;
            }
            else if (pattern.equals(NumberPattern.STANDARD2)) {
                return INT_PREFIX2 + number;
            }
            else if (pattern.equals(NumberPattern.NO_DEF_COUNTRY_CODE)) {
                return number.substring(defaultCountry.length());
            }
            else if (pattern.equals(NumberPattern.NO_INT_PREFIX)) {
                return number;
            }
            else if (pattern.equals(NumberPattern.NATIONAL_PREFIX)) {
                return nationalPrefix[0] + number.substring(defaultCountry.length());
            }
        }
        else if (number.startsWith(INT_PREFIX + defaultCountry)) {
            if (pattern.equals(NumberPattern.STANDARD)) {
                return number;
            }
            else if (pattern.equals(NumberPattern.STANDARD2)) {
                return INT_PREFIX2 + number.substring(1);
            }
            else if (pattern.equals(NumberPattern.NO_DEF_COUNTRY_CODE)) {
                return number.substring(defaultCountry.length() + 1);
            }
            else if (pattern.equals(NumberPattern.NO_INT_PREFIX)) {
                return number.substring(1);
            }
            else if (pattern.equals(NumberPattern.NATIONAL_PREFIX)) {
                return nationalPrefix[0] + number.substring(defaultCountry.length() + 1);
            }
        }
        else if (number.startsWith(INT_PREFIX2 + defaultCountry)) {
            if (pattern.equals(NumberPattern.STANDARD)) {
                return INT_PREFIX + number.substring(2);
            }
            else if (pattern.equals(NumberPattern.STANDARD2)) {
                return number;
            }
            else if (pattern.equals(NumberPattern.NO_DEF_COUNTRY_CODE)) {
                return number.substring(defaultCountry.length() + 2);
            }
            else if (pattern.equals(NumberPattern.NO_INT_PREFIX)) {
                return number.substring(2);
            }
            else if (pattern.equals(NumberPattern.NATIONAL_PREFIX)) {
                return nationalPrefix[0] + number.substring(defaultCountry.length() + 2);
            }
        }
        else if (number.startsWith(INT_PREFIX) || number.startsWith(INT_PREFIX2)) {
            return number;
        }
        else {
            for (String np : nationalPrefix) {
                if (number.startsWith(np)) {
                    if (pattern.equals(NumberPattern.STANDARD)) {
                        return INT_PREFIX + defaultCountry + number.substring(np.length());
                    }
                    else if (pattern.equals(NumberPattern.STANDARD2)) {
                        return INT_PREFIX2 + defaultCountry + number.substring(np.length());
                    }
                    else if (pattern.equals(NumberPattern.NO_DEF_COUNTRY_CODE)) {
                        return number.substring(np.length());
                    }
                    else if (pattern.equals(NumberPattern.NO_INT_PREFIX)) {
                        return defaultCountry + number.substring(np.length());
                    }
                    else {
                        return number;
                    }
                }
            }
            if (pattern.equals(NumberPattern.STANDARD)) {
                return INT_PREFIX + defaultCountry + number;
            }
            else if (pattern.equals(NumberPattern.STANDARD2)) {
                return INT_PREFIX2 + defaultCountry + number;
            }
            else if (pattern.equals(NumberPattern.NO_DEF_COUNTRY_CODE)) {
                return number;
            }
            else if (pattern.equals(NumberPattern.NO_INT_PREFIX)) {
                return defaultCountry + number;
            }
        }
        return number;
    }

    public boolean isValidNumber(String number)
    {
        number = formatNumber(number, NumberPattern.NO_DEF_COUNTRY_CODE);
        return number.matches(numberPattern);
    }

    public boolean isValidMobile(String number)
    {
        number = formatNumber(number, NumberPattern.NO_DEF_COUNTRY_CODE);
        return number.matches(mobilePattern);
    }

    public String getOperator(String number)
    {
        //仅针对移动号码有效
        Set<String> operators = operatorMap.keySet();
        for (String operator : operators) {
            String regex = operatorMap.get(operator);
            if (number.matches(regex)) {
                return operator;
            }
        }
        return null;
    }

    public void setMobilePattern(String mobilePattern)
    {
        this.mobilePattern = mobilePattern;
    }

    public void setNumberPattern(String numberPattern)
    {
        this.numberPattern = numberPattern;
    }

    public void setDefaultCountry(String defaultCountry)
    {
        this.defaultCountry = defaultCountry;
    }

    public void setDefaultPattern(NumberPattern defaultPattern)
    {
        this.defaultPattern = defaultPattern;
    }

    public void setNationalPrefix(String[] nationalPrefix)
    {
        this.nationalPrefix = nationalPrefix;
    }
}
